package com.desay.pangoo.itmt.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.desay.pangoo.common.lite.lang.web.BusinessException;
import com.desay.pangoo.common.lite.lang.web.PangooWebConstant;
import com.desay.pangoo.common.lite.spring.web.ControllerCommonUtils;
import com.desay.pangoo.itmt.controller.vo.TechClassificationVo;
import com.desay.pangoo.itmt.entity.TechClassificationEntity;
import com.desay.pangoo.itmt.entity.WorkGroupEntity;
import com.desay.pangoo.itmt.enums.ExceptionCodeEnum;
import com.desay.pangoo.itmt.repository.TechClassificationRepository;
import com.desay.pangoo.itmt.repository.WorkGroupRepository;
import com.desay.pangoo.itmt.repository.spec.ExpandCriteria;
import com.desay.pangoo.itmt.repository.spec.Restrictions;
import com.desay.pangoo.itmt.service.TechClassificationService;

import cn.hutool.core.collection.CollUtil;

/**
 * @author uidq1163
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TechClassificationServiceImpl implements TechClassificationService {

	@Autowired
	TechClassificationRepository techClassificationRepository;

	@Autowired
	WorkGroupRepository workGroupRepository;

	private static final String FIELD_WORKGROUP = "workGroup.id";

	@Override
	public Long create(TechClassificationVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		TechClassificationEntity techClassificationEntity = new TechClassificationEntity();
		BeanUtils.copyProperties(vo, techClassificationEntity, "id");
		techClassificationEntity.setCreator(user);
		// 检查工作组是否存在
		if (null != vo.getWorkGroupId()) {
			Optional<WorkGroupEntity> option = workGroupRepository.findById(vo.getWorkGroupId());
			if (option.isPresent()) {
				techClassificationEntity.setWorkGroup(option.get());
			} else {
				throw new BusinessException(ExceptionCodeEnum.WORK_GROUP_NOT_EXIST);
			}
		} else {
			throw new BusinessException(ExceptionCodeEnum.WORK_GROUP_NOT_EMPTY);
		}

		// 同一个工作组，分类不能相同
		ExpandCriteria<TechClassificationEntity> c = new ExpandCriteria<>();
		c.add(Restrictions.eq(FIELD_WORKGROUP, vo.getWorkGroupId(), true));
		c.add(Restrictions.eq("classificationName", vo.getClassificationName(), true));
		List<TechClassificationEntity> listExist = techClassificationRepository.findAll(c);
		if (CollUtil.isNotEmpty(listExist)) {
			throw new BusinessException(ExceptionCodeEnum.TECH_CLASSIFICATION_EXIST);
		}

		techClassificationEntity = techClassificationRepository.save(techClassificationEntity);
		return techClassificationEntity.getId();
	}

	@Override
	public void delete(Long id) {
		Optional<TechClassificationEntity> opiton = techClassificationRepository.findById(id);
		if (!opiton.isPresent()) {
			throw new BusinessException(ExceptionCodeEnum.TECH_CLASSIFICATION_NOT_EXIST);
		}
		techClassificationRepository.deleteById(id);
	}

	@Override
	public void update(Long id, TechClassificationVo vo) {
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		TechClassificationEntity techClassificationEntity = null;
		Optional<TechClassificationEntity> opiton = techClassificationRepository.findById(id);
		if (opiton.isPresent()) {
			techClassificationEntity = opiton.get();
		} else {
			throw new BusinessException(ExceptionCodeEnum.TECH_CLASSIFICATION_NOT_EXIST);
		}
		if (!vo.getVersion().equals(techClassificationEntity.getVersion())) {
			throw new BusinessException(ExceptionCodeEnum.DATA_VERSION_ERROR);
		}
		// 检查工作组是否存在
		if (null != vo.getWorkGroupId()) {
			Optional<WorkGroupEntity> option = workGroupRepository.findById(vo.getWorkGroupId());
			if (option.isPresent()) {
				techClassificationEntity.setWorkGroup(option.get());
			} else {
				throw new BusinessException(ExceptionCodeEnum.WORK_GROUP_NOT_EXIST);
			}
		} else {
			throw new BusinessException(ExceptionCodeEnum.WORK_GROUP_NOT_EMPTY);
		}
		ExpandCriteria<TechClassificationEntity> c = new ExpandCriteria<>();
		// 同一个工作组，分类不能相同
		c.add(Restrictions.eq(FIELD_WORKGROUP, vo.getWorkGroupId(), true));
		c.add(Restrictions.ne("id", id, true));
		c.add(Restrictions.eq("classificationName", vo.getClassificationName(), true));
		List<TechClassificationEntity> listExist = techClassificationRepository.findAll(c);
		if (CollUtil.isNotEmpty(listExist)) {
			throw new BusinessException(ExceptionCodeEnum.TECH_CLASSIFICATION_EXIST);
		}
		BeanUtils.copyProperties(vo, techClassificationEntity, "id");
		techClassificationEntity.setUpdator(user);
		techClassificationRepository.save(techClassificationEntity);
	}

	@Override
	public Page<TechClassificationEntity> getList(Integer pageSize, Integer pageNum, Long workGroupId) {
		ExpandCriteria<TechClassificationEntity> c = new ExpandCriteria<>();
		// 根据组查询
		c.add(Restrictions.eq(FIELD_WORKGROUP, workGroupId, true));
		List<Order> orders = new ArrayList<>();
		Order order = new Order(Sort.Direction.ASC, "createTime");
		orders.add(order);
		Pageable pageReq = PageRequest.of(pageNum - 1, pageSize, Sort.by(orders));
		return techClassificationRepository.findAll(c, pageReq);
	}

	@Override
	public List<TechClassificationEntity> getAllList(Long workGroupId) {
		ExpandCriteria<TechClassificationEntity> c = new ExpandCriteria<>();
		// 根据组查询
		c.add(Restrictions.eq(FIELD_WORKGROUP, workGroupId, true));
		return techClassificationRepository.findAll(c, Sort.by(Sort.Direction.ASC, "createTime"));
	}

}
